package com.csdj.payment.service;

import com.csdj.beans.entity.Balance;
import com.csdj.beans.entity.Order;
import com.csdj.beans.entity.PayHis;
import com.csdj.beans.entity.PayHisExample;
import com.csdj.beans.interfaces.pay.IPayService;
import com.csdj.common.PayException;
import com.csdj.common.WebResult;
import com.csdj.common.constant.PaymentConstant;
import com.csdj.common.constant.WebResultConstant;
import com.csdj.common.utils.JsonUtil;
import com.csdj.middleware.RocketMqProducer;
import com.csdj.payment.mapper.BalanceMapper;
import com.csdj.payment.mapper.PayHisMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
@DubboService
public class PayService implements IPayService {

    private Logger log = LoggerFactory.getLogger("paymenet");

    @Resource
    private BalanceMapper balanceMapper;
    @Resource
    private PayHisMapper payHisMapper;
    @Resource
    private RocketMqProducer rocketMqProducer;
    @Value("${mq.rocket.producer.topic}")
    private String topic;

    @Override
    public Balance getByUid(int uid) {
        return balanceMapper.selectByPrimaryKey(uid);
    }

    /**
     * 用户支付订单
     * 前提条件：一个积分等于一分钱，
     * @param order
     * @return
     */
    @Transactional(rollbackFor = PayException.class)
//    @Override
    public int updateBalance(Order order,byte type) {
        //1.计算需要扣减多少钱，
        BigDecimal credits = BigDecimal.valueOf(order.getPoints()*0.01);
        //商品总金额
        BigDecimal amount = order.getPrice().multiply(BigDecimal.valueOf(order.getQuantity()));
        //需要支付的金额  把总金额减去积分兑换的金额
        BigDecimal payment = amount.subtract(credits);
        //2.扣除余额
        Balance balance = balanceMapper.selectByPrimaryKey(order.getUserId());
        if(balance == null){
            log.info("uid:{} 没有余额记录",order.getUserId());
            return WebResultConstant.PAY_BANACE_IS_NULL;
        }
        if(balance.getBalance().compareTo(payment)<0){
            log.info("uid:{}余额不足 balance:{} payment:{}",order.getUserId(),balance.getBalance(),payment);
            return WebResultConstant.PAY_BALANCE_NOT_ENCOUTH;
        }
        if(balanceMapper.updateBalance(order.getUserId(),payment,balance.getVersion())>0){
            //更新成功
            //3.添加记录
            PayHis his = new PayHis();
            his.setAmount(payment);
            his.setBalance(balance.getBalance().subtract(payment));
            his.setCreateTm(new Date());
            his.setUid(order.getUserId());
            his.setOrderid(order.getId());
            his.setPayType(type);
            if(payHisMapper.insert(his)>0){
                log.info("订单：{} 支付成功",order.getId());
                return WebResultConstant.SUCCESS;
            }else{
                throw new PayException("添加支付记录失败！");
            }
        }else{
            log.info("用户:{}  订单：{}",order.getUserId(),order.getId());
            return WebResultConstant.PAY_FAIL;
        }
    }

    @Override
    public List<PayHis> getPayHis(int uid) {
        PayHisExample example = new PayHisExample();
        example.createCriteria().andUidEqualTo(uid);
        example.setOrderByClause("id desc");
        return payHisMapper.selectByExample(example);
    }

    @Override
    public boolean startPayment(Order order, byte type) {
        final SendResult sendResult = rocketMqProducer.sendTranscationMsg(topic, PaymentConstant.PAYMENT_TAG, JsonUtil.objectToString(order), type);
        if(SendStatus.SEND_OK.equals(sendResult.getSendStatus())){
            return true;
        }
        log.info("支付事务消息失败");
        return false;
    }

    /**
     * 根据订订单查询支付记录
     * @param orderId
     * @return
     */
    @Override
    public PayHis getHisByOrdreId(int orderId){
        PayHisExample example = new PayHisExample();
        example.createCriteria().andOrderidEqualTo(orderId);
        return payHisMapper.selectOneByExample(example);
    }
}
